﻿/***

    应用程序的单例运行模式操作类

    Austin Liu 刘恒辉
    Project Manager and Software Designer

    E-Mail: lzhdim@163.com
    Blog:   http://lzhdim.cnblogs.com
    Date:   2024-01-15 15:18:00

    说明：
        1、应用程序唯一运行判断；
        2、应用程序单一目录运行判断；
        3、获取当前应用程序进程；

    使用方法：
        if (AppInstance.IsUniqueRunning())
        {
            return;
        }

***/

namespace Lzhdim.ProgramInstance
{
    using System;
    using System.Diagnostics;
    using System.IO;
    using System.Linq;
    using System.Reflection;
    using System.Runtime.InteropServices;
    using System.Threading;

    /// <summary>
    /// 单例程序操作类
    /// </summary>
    internal class AppInstance
    {
        private static Mutex _mutex;

        /// <summary>
        /// 获取当前程序进程实例
        /// </summary>
        /// <returns>程序进程实例</returns>
        internal static Process GetAppProcess()
        {
            Process currentProcess = Process.GetCurrentProcess();
            foreach (Process process in Process.GetProcessesByName(currentProcess.ProcessName))
            {
                if (Assembly.GetExecutingAssembly().Location.Replace("/", @"\") == process.MainModule.FileName)
                {
                    return process;
                }
            }

            return null;
        }

        /// <summary>
        /// 判断程序是否运行（在同一目录只运行一个实例，不同目录能够运行另一个实例）
        /// </summary>
        /// <returns>true 已经运行；false 未运行</returns>
        internal static bool IsDirRuning()
        {
            new Mutex(true, System.Reflection.Assembly.GetExecutingAssembly().Location.Replace(Path.DirectorySeparatorChar, '_'), out bool createdNew);

            if (!createdNew)
            {
                Process current = Process.GetCurrentProcess();
                foreach (Process process in Process.GetProcessesByName(current.ProcessName))
                {
                    if (process.Id != current.Id)
                    {
                        return true;
                    }
                }
            }

            return false;
        }

        /// <summary>
        /// 程序是否已经运行（唯一运行）
        /// </summary>
        /// <returns>true 已经运行；false 未运行</returns>
        internal static bool IsPrevInstance()
        {
            try
            {
                var pc = Process.GetCurrentProcess();
                var procs = Process.GetProcessesByName(pc.ProcessName);
                return procs.Any(p => p.Id != pc.Id);
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// 程序是否运行（唯一运行）
        /// </summary>
        /// <returns>true 程序已运行；false 程序未运行</returns>
        internal static bool IsUniqueRunning()
        {
            _mutex = new Mutex(initiallyOwned: true, new Guid(((GuidAttribute)Attribute.GetCustomAttribute(Assembly.GetExecutingAssembly(), typeof(GuidAttribute))).Value).ToString("N"), out bool createdNew);
            return !createdNew;
        }
    }
}